// 数字枚举   ->原理：反向映射
enum Role {
  Reporter = 1,
  Developer,
  Maintainer,
  Owner,
  Guest
}
console.log(Role.Reporter)
console.log(Role)

// 字符串枚举
enum Message {
  Success = '恭喜您， 成功了',
  Fail = '抱歉，失败了'
}

//异构枚举   不建议使用
enum Answer {
  N,
  Y = "yes"
}

// 枚举成员  （常量，常量引用，计算枚举成员）
// Role.Reporter = 2
enum Char {
  a,
  b = Char.a,
  c = 1 + 3,
  d = Math.random(),
  e = '123'.length,
  f = 4
}

// 常量枚举
const enum Month {
  Jan,
  Feb,
  Mar
}
let month = [Month.Jan, Month.Feb, Month.Mar]

// 枚举类型
enum E { a, b }
enum F { a = 0, b = 1 }

// interface对象接口
interface List {
  id: number;
  name: String;
  age?: number
  // [x: string]: any
}
interface Result {
  data: List[]
}

function render(result: Result) {
  result.data.forEach((value) => {
    console.log(value.id, value.name)
    if (value.age) {
      console.log(value.age)
    }
    value.id++
  })
}

let result = {
  data: [
    { id: 1, name: 'a', sex: 'male' },
    { id: 2, name: 'b' }
  ]
}

render({
  data: [
    { id: 1, name: 'a', sex: 'male' },
    { id: 2, name: 'b' }
  ]
} as Result) //类型断言
// render(result)

interface StringArray {
  [index: number]: string
}
let chars: StringArray = ['a', 'b']

interface Names {
  [x: string]: string;
  // y:number
  [z: number]: string
}
//interface 函数接口
// let fun: (x: number, y: number) => number
// interface fun {
//   (x: number, y: number): number
// }
type Fun = (x: number, y: number) => number
let fun: Fun = (a, b) => a + b
interface Lib {
  (): void;
  version: string;
  doSomething(): void;
}

function getLib() {
  let lib: Lib = (() => { }) as Lib
  lib.version = '1.0';
  lib.doSomething = () => { }
  return lib
}

let lib1 = getLib()
lib1()
lib1.doSomething()
let lib2 = getLib();

//定义函数地方式
function resolve1(x: number, y: number) {
  return x + y
}
let resolve2: (x: number, y: number) => number
type resolve3 = (x: number, y: number) => number
interface resolve4 {
  (x: number, y: number): number
}

// resolve1(1, 2)
// 必选参数必须放在可选参数之前
function resolve5(x: number, y?: number) {
  return y ? x + y : x
}
resolve5(5)

// 函数定义默认值
function resolve6(x: number, y = 0, z: number, q = 1) {
  return x + y + z + q
}
resolve6(1, undefined, 3) // 如果第二个参数不传  就会把3赋值给y

function resolve7(x: number, ...rest: number[]) {
  return x + rest.reduce((pre, cur) => pre + cur)
}
console.log(resolve7(1, 2, 3, 4, 5), '------7')

// 函数重载 
function resolve8(...rest: number[]): number
function resolve8(...rest: string[]): string
function resolve8(...rest: any[]): any {
  let first = rest[0];
  if (typeof first === 'string') {
    return rest.join('')
  }
  if (typeof first === 'number') {
    return rest.reduce((pre, cur) => cur + pre)
  }
}
console.log(resolve8(1, 2, 3, 4, 5), '-----8')
console.log(resolve8('a', 'b', 'c'), '-----8')